package com.dykj.fireFighting.web.controller.GB26875Controller;

import com.alibaba.fastjson.JSON;
import com.dykj.fireFighting.api.base.devHisResult.service.IDevHisResultService;
import com.dykj.fireFighting.api.base.effecttimesetting.entity.EffectiveTimeSetting;
import com.dykj.fireFighting.api.base.emergency.entity.EmergencyStaff;
import com.dykj.fireFighting.api.base.emergency.service.IEmergencyStaffService;
import com.dykj.fireFighting.api.base.news.service.IAliMessageService;
import com.dykj.fireFighting.api.base.push.service.PushService;
import com.dykj.fireFighting.api.elasticsearch.devHis.entity.EsDevHis;
import com.dykj.fireFighting.api.elasticsearch.devHis.service.EsDevHisService;
import com.dykj.fireFighting.api.elasticsearch.devHisWater.entity.EsDevHisWater;
import com.dykj.fireFighting.api.elasticsearch.devHisWater.service.EsDevHisWaterService;
import com.dykj.fireFighting.common.core.constant.WebsocketConstant;
import com.dykj.fireFighting.common.starter.redisson.service.RedisService;
import com.dykj.fireFighting.web.base.websocket.entity.MoreMessage;
import com.dykj.fireFighting.web.contact.PubContacts;
import com.dykj.fireFighting.web.model.Device;
import com.dykj.fireFighting.web.model.DeviceFault;
import com.dykj.fireFighting.web.model.Manufactor;
import com.dykj.fireFighting.web.model.SuspectedFire;
import com.dykj.fireFighting.web.model.report.*;
import com.dykj.fireFighting.web.model.vo.DevHisVo;
import com.dykj.fireFighting.web.model.vo.SocialUnitVo;
import com.dykj.fireFighting.web.rocketmq.message.DevHisSSPushMessage;
import com.dykj.fireFighting.web.rocketmq.message.FirePushMessage;
import com.dykj.fireFighting.web.rocketmq.message.WaterPushMessage;
import com.dykj.fireFighting.web.rocketmq.message.ZcPushMessage;
import com.dykj.fireFighting.web.rocketmq.producer.*;
import com.dykj.fireFighting.web.service.*;
import com.dykj.fireFighting.web.utils.BeanContext;
import com.dykj.fireFighting.web.utils.HttpClient;
import com.dykj.fireFighting.web.utils.UUIDUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.quickserver.net.model.DevType;
import org.quickserver.net.model.GB268753QN;
import org.quickserver.net.model.GB268753QNS;
import org.quickserver.net.model.GB268753QNSZGW;
import org.quickserver.net.server.*;
import org.quickserver.util.data.dataProcessing;
import org.springframework.beans.BeanUtils;
import testmain.EchoServerData;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;


public class GB26875Controller implements ClientCommandHandler, ClientEventHandler, ClientBinaryHandler {

    private DevHisService devHisService;
    private ManufactorService manufactorService;
    private DevHisZcService devHisZcService;
    private SysUserService sysUserService;
    private RedisService redisService;
    private SuspectedFireService suspectedFireService;
    private IAliMessageService aliMessageService;
    private PushService pushService;
    private EsDevHisService esDevHisService;
    private EsDevHisWaterService esDevHisWaterService;
    private IDevHisResultService devHisResultService;
    private InsertDevHisProducer insertDevHisProducer;
    private InsertDevHisZcProducer insertDevHisZcProducer;
    private FirePushProducer firePushProducer;
    private InsertDevHisWaterProducer insertDevHisWaterProducer;
    private WaterPushProducer waterPushProducer;
    private ZcPushProducer zcPushProducer;
    private IEmergencyStaffService iEmergencyStaffService;
    private InsertDevHisSsProducer insertDevHisSsProducer;
    private DevHisSsPushProducer devHisSsPushProducer;
    public GB26875Controller() {
        this.aliMessageService = (IAliMessageService) BeanContext.getApplicationContext().getBean("aliMessageService");
        this.devHisResultService = (IDevHisResultService) BeanContext.getApplicationContext().getBean("devHisResultService");
        this.esDevHisService = (EsDevHisService) BeanContext.getApplicationContext().getBean("esDevHisService");
        this.esDevHisWaterService = (EsDevHisWaterService) BeanContext.getApplicationContext().getBean("esDevHisWaterService");
        this.pushService = (PushService) BeanContext.getApplicationContext().getBean("pushService");
        this.manufactorService = BeanContext.getApplicationContext().getBean(ManufactorService.class);
        this.devHisService = BeanContext.getApplicationContext().getBean(DevHisService.class);
        this.devHisZcService = BeanContext.getApplicationContext().getBean(DevHisZcService.class);
        this.suspectedFireService = BeanContext.getApplicationContext().getBean(SuspectedFireService.class);
        this.redisService = BeanContext.getApplicationContext().getBean(RedisService.class);
        this.sysUserService = BeanContext.getApplicationContext().getBean(SysUserService.class);
        this.insertDevHisProducer = BeanContext.getApplicationContext().getBean(InsertDevHisProducer.class);
        this.insertDevHisZcProducer = BeanContext.getApplicationContext().getBean(InsertDevHisZcProducer.class);
        this.firePushProducer = BeanContext.getApplicationContext().getBean(FirePushProducer.class);
        this.insertDevHisWaterProducer = BeanContext.getApplicationContext().getBean(InsertDevHisWaterProducer.class);
        this.waterPushProducer = BeanContext.getApplicationContext().getBean(WaterPushProducer.class);
        this.zcPushProducer = BeanContext.getApplicationContext().getBean(ZcPushProducer.class);
        this.iEmergencyStaffService = (IEmergencyStaffService) BeanContext.getApplicationContext().getBean("iEmergencyStaffService");
        this.devHisSsPushProducer=BeanContext.getApplicationContext().getBean(DevHisSsPushProducer.class);
        this.insertDevHisSsProducer=BeanContext.getApplicationContext().getBean(InsertDevHisSsProducer.class);

    }

    /**
     * 连接服务时响应相关的信息
     */

    @Override
    public void gotConnected(ClientHandler handler)
            throws SocketTimeoutException, IOException {
        //设置请求和响应的数据类型的信息
        handler.setDataMode(DataMode.BINARY, DataType.IN);

        handler.setDataMode(DataMode.BINARY, DataType.OUT);

        //设置相关的连接成功的信息
        //        handler.sendClientMsg("+++++++++++++++++++++++++++++++");
        //        handler.sendClientMsg("| Welcome to EchoServer v 1.0 |");
        //        handler.sendClientMsg("|        Send 'Quit' to exit  |");
        //        handler.sendClientMsg("+++++++++++++++++++++++++++++++");
        handler.sendSystemMsg(
                "Connection on : " + handler.getSocket().getInetAddress()
        );
    }

    /**
     * 连接断开时候返回的信息
     */
    @Override
    public void lostConnection(ClientHandler handler) throws IOException {
        handler.sendSystemMsg(
                "Connection lost : " + handler.getSocket().getInetAddress()
        );
        // System.out.println(11111);
    }

    /**
     * 正在关闭时候响应的信息
     */
    @Override
    public void closingConnection(ClientHandler handler) throws IOException {
        handler.sendSystemMsg(
                "Closing connection : " + handler.getSocket().getInetAddress()
        );
        // System.out.println(22222);
    }

    /**
     * 此方法为ClientCommandHandler接口的核心方法，因为服务器接受客户端发送的任何命令时
     * 都要盗用该方法，
     * 处理客户端的请求的信息
     */
    @Override
    public void handleCommand(ClientHandler handler, String command)
            throws SocketTimeoutException, IOException {
        System.out.println(command);
        byte[] a = command.getBytes();

        System.out.println(stringToHexString(command));
        if ("00".equals(stringToHexString(command))) {
            handler.closeConnection();
        } else {
            handler.sendClientBinary(a);
        }
    }

    public static String stringToHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = s.charAt(i);
            String s4 = Integer.toHexString(ch);
            if (s4.length() == 1) {
                s4 = "0" + s4;
            }
            str = str + s4;
        }
        return str;
    }

    @Override
    public void handleBinary(ClientHandler handler, byte[] command)
            throws SocketTimeoutException, IOException {
        EchoServerData ec = (EchoServerData) handler.getClientData();
        String[] a = dataProcessing.bytesToHexStrings(command);
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
    }

    /**
     * 监听新型水设备返回的信息
     *
     * @param clientHandler
     * @param gb268753QNS
     * @throws SocketTimeoutException
     * @throws IOException
     */
    @Override
    public void handleGB268753QN(ClientHandler clientHandler, GB268753QNS gb268753QNS) throws SocketTimeoutException, IOException {
        HttpClient.doPost(
                PubContacts.addressJar + "app/devHisJar/handleWater",
                gb268753QNS
        );
    }

    /**
     * 监听上海庄诚返回数据
     *
     * @param clienthandler
     * @param obj
     * @throws SocketTimeoutException
     * @throws IOException
     */
    @Override
    public void handleGB268753QN(ClientHandler clienthandler, DevHisZc obj)
            throws SocketTimeoutException, IOException {
        if (null == obj){
            return;
        }
        if (null == obj.getDevCode()){
            return;
        }
        Device device = JSON.parseObject((String) redisService.get(obj.getDevCode()), Device.class);
        if (device == null) {
            device = devHisService.queryCreateBy(obj.getDevCode());
        }
        if (device == null) {
            return;
        }
        redisService.set(obj.getDevCode(), JSON.toJSONString(device));
        obj.setUpTime(new Date());
        Map<String, String> zt = obj.getComponentStateMap();
        List<String> bjztSm = new ArrayList<String>();
        List<String> bjzt = new ArrayList<String>();
        if (null != zt && zt.size() > 0) {
            for (Map.Entry<String, String> entry : zt.entrySet()) {
                bjzt.add(entry.getKey());
                bjztSm.add(entry.getValue());
            }
        }
        obj.setBjzt(String.join(",", bjzt)); //部件状态码
        obj.setBjztSm(String.join(",", bjztSm)); //部件状态中文说明
        obj.setId((UUIDUtils.getTimeUUID()));

        //虚拟一个主机，调用通过主机获取推送人的方法
        Manufactor manufactor = new Manufactor();
        manufactor.setIdentification(device.getRelationId());
        manufactor.setUnitId(device.getUnitId());
        manufactor.setUnitName(device.getUnitName());

        //获取单位信息
        SocialUnitVo unit = getContacts(manufactor);
        obj.setUnitName(device.getUnitName());
        obj.setUnitId(device.getUnitId());
        obj.setCenterUnitId(unit.getCenterUnitId());
        obj.setDeviceName(device.getName());
        redisService.set(obj.getDevCode()+"_realtime", JSON.toJSONString(obj));
        //庄诚设备实时状态
        redisService.set(device.getRelationId()+"_realtime_device", JSON.toJSONString(device));
        if (bjzt.contains("1001") || bjzt.contains("1002") || bjzt.contains("1003") || bjzt.contains("1011")  || bjzt.contains("1012") || bjzt.contains("1013") ||
                bjzt.contains("1014") || bjzt.contains("1021") || bjzt.contains("1022") || bjzt.contains("1023") || bjzt.contains("1024") || bjzt.contains("1025") ||
                bjzt.contains("1026") || bjzt.contains("1031") ) {
            StringJoiner stringJoiner = new StringJoiner(",");
            boolean flag=false;
            if (bjzt.contains("1001")){
                flag=true;
                stringJoiner.add("电流A报警");
            }
            if (bjzt.contains("1002")) {
                flag=true;
                stringJoiner.add("电流B报警");
            }
            if (bjzt.contains("1003")) {
                flag=true;
                stringJoiner.add("电流C报警");
            }
            if (bjzt.contains("1011")) {
                flag=true;
                stringJoiner.add("温度A报警");
            }
            if (bjzt.contains("1012")) {
                flag=true;
                stringJoiner.add("温度B报警");
            }
            if (bjzt.contains("1013")) {
                flag=true;
                stringJoiner.add("温度C报警");
            }
            if (bjzt.contains("1014")) {
                flag=true;
                stringJoiner.add("温度N报警");
            }
            if (bjzt.contains("1021")) {
                flag=true;
                stringJoiner.add("电压A欠压");
            }
            if (bjzt.contains("1022")) {
                flag=true;
                stringJoiner.add("电压A过压");
            }
            if (bjzt.contains("1023")) {
                flag=true;
                stringJoiner.add("电压B欠压");
            }
            if (bjzt.contains("1024")) {
                flag=true;
                stringJoiner.add("电压B过压");
            }
            if (bjzt.contains("1025")) {
                flag=true;
                stringJoiner.add("电压C欠压");
            }
            if (bjzt.contains("1026")) {
                flag=true;
                stringJoiner.add("电压C过压");
            }
            if (bjzt.contains("1031")) {
                flag=true;
                stringJoiner.add("漏电报警");
            }
            //以上if判断没作用，仅用于显示状态
            System.out.println("=====报警状态"+stringJoiner);
            device.setStatus(stringJoiner.toString());
            //庄诚设备实时状态
            redisService.set(device.getRelationId()+"_realtime_device", JSON.toJSONString(device));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time ="";
            if(null != obj.getZtfssj()){
                time =sdf.format(obj.getZtfssj()).substring(11);
            }else{
                time =sdf.format(new Date()).substring(11);
            }

            List<EmergencyStaff> emergencyStaffList;
            emergencyStaffList = getZcEgencyStaffList(manufactor);
            if(emergencyStaffList.size()>0){
                aliMessageService.sendAliMessageBatch(emergencyStaffList, "唐山臻旭科技有限公司", "SMS_212709090", device.getName(), time,"");
                aliMessageService.sendAliVoiceBatch("", emergencyStaffList, "TTS_212477607", device.getName(), time);

            }

            //入库
            insertDevHisZcProducer.asyncSend(obj, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.println("=======发送插入DevHisZc消息成功=======");
                }

                @Override
                public void onException(Throwable throwable) {
                    System.out.println("=======发送插入DevHisZc消息失败=======");
                }
            });
            if(flag){
                devHisResultService.saveOne(3, manufactor.getUnitId(), "");
            }

            //推送
            ZcPushMessage zcPushMessage = new ZcPushMessage();
            zcPushMessage.setAlarmTime(time);
            zcPushMessage.setDevice(device);
            zcPushMessage.setUnit(unit);
            zcPushMessage.setDevHisId(obj.getId());
            zcPushMessage.setDeviceName(device.getName());
            zcPushProducer.asyncSend(zcPushMessage, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.println("=======发送推送消息成功=======");
                }

                @Override
                public void onException(Throwable throwable) {
                    System.out.println("=======发送推送消息失败=======");
                }
            });
        }



    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] b = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节
            b[i / 2] =
                    (byte) (
                            (Character.digit(s.charAt(i), 16) << 4) +
                                    Character.digit(s.charAt(i + 1), 16)
                    );
        }
        return b;
    }

    public static final String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    public void handleBinaryStrings(ClientHandler handler, String[] strs)
            throws SocketTimeoutException, IOException {
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
    }

    /**
     * 苏州国网水设备
     *
     * @param clienthandler
     * @param gb268753qn
     * @throws SocketTimeoutException
     * @throws IOException
     */
    @Override
    public void handleGB268753QN(ClientHandler clienthandler, List<GB268753QNSZGW> gb268753qn)
            throws SocketTimeoutException, IOException {
        if (null != gb268753qn && gb268753qn.size() > 0) {
            //判断设备主机是否在线
            String manufactorIdentification = gb268753qn.get(0).getUniqueCode();
            Manufactor manufactor = JSON.parseObject((String) redisService.get(manufactorIdentification), Manufactor.class);
            if (manufactor == null) {
                manufactor = manufactorService.selectCreateBy(manufactorIdentification);
            }
            if (manufactor == null) {
                return;
            }
            if (!"1".equals(manufactor.getIsOnline())) {
                manufactor.setIsOnline("1");
                manufactorService.updateStatusByIdentification(manufactor);
                redisService.set(manufactor.getIdentification(), JSON.toJSONString(manufactor));
            }

            try {
                for (int i = 0; i < gb268753qn.size(); i++) {
                    GB268753QNSZGW q = gb268753qn.get(i);
                    int channelNumber = i + 1;
                    String relationId="";
                    if (StringUtils.isNotBlank(q.getMoniType())) {
                        relationId = q.getUniqueCode() + "-" + channelNumber+"-"+"1";
                    }else{
                        relationId = q.getUniqueCode() + "-" + channelNumber+"-2";
                    }
                    //获取水设备
                    Boolean haskey = redisService.hasKey(relationId);
                    Device device = JSON.parseObject((String) redisService.get(relationId), Device.class);
                    if (device == null && !haskey) {
                        device = devHisService.queryCreateBy(relationId);
                        if (device == null) {
                            redisService.set(relationId, null);
                        }
                    }
                    if (device != null) {
                        //获取单位信息
                        SocialUnitVo unit = getContacts(manufactor);

                        DevHisWater devHisWater = new DevHisWater();
                        devHisWater.setId(UUIDUtils.getTimeUUID());
                        devHisWater.setRelationId(relationId);
                        devHisWater.setManufactorIdentification(q.getUniqueCode());
                        devHisWater.setUploadTime(q.getUploadTime());
                        devHisWater.setStateTime(q.getStateTime());
                        devHisWater.setSysType(q.getSysType());
                        devHisWater.setSysAddress(q.getSysAddress());
                        devHisWater.setComponentType(q.getComponentType());
                        devHisWater.setComponentAddress(q.getComponentAddress());
                        devHisWater.setComponentExplain(q.getComponentExplain());
                        devHisWater.setUnitId(device.getUnitId());
                        devHisWater.setUnitName(unit.getUnitName());
                        devHisWater.setCenterUnitId(unit.getCenterUnitId());
                        devHisWater.setDeviceName(device.getName());
                        devHisWater.setDevId(device.getId());
                        devHisWater.setDevType(device.getMoniType());

                        if (StringUtils.isNotBlank(q.getMoniType())) {//解析模拟量
                            BigDecimal b = new BigDecimal((device.getK() * Integer.parseInt(q.getMoniValue()) - device.getB()) / 1000);//计算模拟量值
                            double value = b.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();//取三位小数
                            if (value < 0) {
                                value = 0;
                            }

                            devHisWater.setMoniValue(q.getMoniValue());
                            devHisWater.setMoniType(device.getMoniType());
                            devHisWater.setCalculationValue(value);
                            device.setCalculationValue(value);
                            System.out.println("====value=" + value+"===阈值下限="+device.getThresholdL()+"===阈值上限="+device.getThresholdH()
                                    +"===模拟量="+q.getMoniValue()+"===模拟量类型0-液位；1-压力="+device.getMoniType()
                                    +"===K值="+device.getK()+"===B值="+device.getB());
                            boolean pushSwitch = false;//推送开关
                            //是否入库
                            boolean insertSwitch = true;

                            int alarmNum = 0;
                            Object object = redisService.get(device.getRelationId() + "_alarmNum");
                            if (object != null) {
                                alarmNum = (int) object;
                            }

                            if (device.getAlarmNumber() == 0) {
                                pushSwitch = true;
                            } else {
                                if (alarmNum < device.getAlarmNumber()) {
                                    pushSwitch = true;
                                }
                            }

                            List<EmergencyStaff> emergencyStaffList;
                            emergencyStaffList = getWaterEgencyStaffList(manufactor);


                            if (value < device.getThresholdL()) {//低限报警
                                redisService.set(device.getRelationId() + "_alarmNum", alarmNum + 1);
                                if ("0".equals(device.getMoniType())) {
                                    devHisWater.setComponentStatus("液位低限报警");
                                } else {
                                    devHisWater.setComponentStatus("压力低限报警");
                                }
                                devHisResultService.saveOne(3, manufactor.getUnitId(), "");
                            } else if (value > device.getThresholdH()) {//高限报警
                                redisService.set(device.getRelationId() + "_alarmNum", alarmNum + 1);
                                if ("0".equals(device.getMoniType())) {
                                    devHisWater.setComponentStatus("液位高限报警");
                                } else {
                                    devHisWater.setComponentStatus("压力高限报警");
                                }
                                devHisResultService.saveOne(3, manufactor.getUnitId(), "");
                            } else {//正常
                                //获取设备状态
                                String status = device.getStatus();
                                if (StringUtils.isNotBlank(status) && status.contains("液位") && status.contains("报警")) {
                                    redisService.del(device.getRelationId() + "_alarmNum");
                                    devHisWater.setComponentStatus("液位恢复");
                                    pushSwitch = true;
                                } else if (StringUtils.isNotBlank(status) && status.contains("压力") && status.contains("报警")) {
                                    redisService.del(device.getRelationId() + "_alarmNum");
                                    devHisWater.setComponentStatus("压力恢复");
                                    pushSwitch = true;
                                } else {
                                    devHisWater.setComponentStatus("正常");
                                    redisService.del(device.getRelationId() + "_alarmNum");
                                    pushSwitch = false;
                                    insertSwitch = false;
                                }
                            }
                            device.setStatus(devHisWater.getComponentStatus());
                            redisService.set(relationId, JSON.toJSONString(device));
                            redisService.set(relationId+"_realtime", JSON.toJSONString(device));
                            //报警数据入库
                            if (insertSwitch) {
                                insertDevHisWaterProducer.asyncSend(devHisWater, new SendCallback() {
                                    @Override
                                    public void onSuccess(SendResult sendResult) {
                                        System.out.println("=======发送插入DevHisWater消息成功=======");
                                    }
                                    @Override
                                    public void onException(Throwable throwable) {
                                        System.out.println("=======发送插入DevHisWater消息失败=======");
                                    }
                                });
                            }

                            if (pushSwitch) {
                                //websocket推送和app推送
                                WaterPushMessage waterPushMessage = new WaterPushMessage();
                                waterPushMessage.setDevice(device);
                                waterPushMessage.setUnit(unit);
                                waterPushMessage.setAlarmTime(devHisWater.getStateTime());
                                waterPushMessage.setDevHisId(devHisWater.getId());
                                waterPushMessage.setIsAppPush(true);
                                waterPushProducer.asyncSend(waterPushMessage, new SendCallback() {
                                    @Override
                                    public void onSuccess(SendResult sendResult) {
                                        System.out.println("=======发送消息成功=======");
                                    }
                                    @Override
                                    public void onException(Throwable throwable) {
                                        System.out.println("=======发送消息失败=======");
                                    }
                                });
                                //短信语音推送 待添加
                                if (device.getStatus().contains("报警")){
                                    if(emergencyStaffList.size()>0){
                                        aliMessageService.sendAliMessageBatch(emergencyStaffList, "唐山臻旭科技有限公司", "SMS_213772600", device.getName(), devHisWater.getUploadTime(),devHisWater.getComponentStatus());
                                    }

                                }else {
                                    if(emergencyStaffList.size()>0) {
                                        aliMessageService.sendAliMessageBatch(emergencyStaffList, "唐山臻旭科技有限公司", "SMS_214527311", device.getName(), devHisWater.getUploadTime(), "");
                                    }
                                }
                            }
                        } else {//解析开关量
                            System.out.println("============" + q.toString() + "===========");
                            Map map = q.getComponentStateMap();
                            String str;
                            Object onOff = redisService.get(relationId + "On-Off");
                            if (null == onOff) {
                                str = "";
                            }else {
                                str = (String) onOff;
                            }
                            if (map.containsKey("08")) {
                                System.out.println("============" + relationId+ "开关量关闭=============");
                                devHisWater.setComponentStatus("关闭");
                                redisService.set(relationId + "On-Off","Off");
                                if (str.equals("On") || str.equals("")){
                                    //开关量入数据库
                                    insertDevHisWaterProducer.asyncSend(devHisWater, new SendCallback() {
                                        @Override
                                        public void onSuccess(SendResult sendResult) {
                                            System.out.println("=======发送插入DevHisWater消息成功=======");
                                        }
                                        @Override
                                        public void onException(Throwable throwable) {
                                            System.out.println("=======发送插入DevHisWater消息失败=======");
                                        }
                                    });
                                }

                            }else {
                                System.out.println("============" + relationId + "开关量开启==============");
                                devHisWater.setComponentStatus("开启");
                                redisService.set(relationId + "On-Off","On");
                                if (str.equals("Off") || str.equals("")){
                                    //开关量入数据库
                                    insertDevHisWaterProducer.asyncSend(devHisWater, new SendCallback() {
                                        @Override
                                        public void onSuccess(SendResult sendResult) {
                                            System.out.println("=======发送插入DevHisWater消息成功=======");
                                        }
                                        @Override
                                        public void onException(Throwable throwable) {
                                            System.out.println("=======发送插入DevHisWater消息失败=======");
                                        }
                                    });
                                }
                            }

                        }
                    }


                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    public void handleGB268753QN(ClientHandler clienthandler, DevHisSs obj) throws SocketTimeoutException, IOException {
        if (null == obj){
            return;
        }
        if (null == obj.getDevCode()){
            return;
        }
        Device device = JSON.parseObject((String) redisService.get(obj.getDevCode()), Device.class);
        if (device == null) {
            device = devHisService.queryCreateBy(obj.getDevCode());
        }
        if (device == null) {
            return;
        }
        redisService.set(obj.getDevCode(), JSON.toJSONString(device));
        obj.setUpTime(new Date());

        obj.setId((UUIDUtils.getTimeUUID()));

        //虚拟一个主机，调用通过主机获取推送人的方法
        Manufactor manufactor = new Manufactor();
        manufactor.setIdentification(device.getRelationId());
        manufactor.setUnitId(device.getUnitId());
        manufactor.setUnitName(device.getUnitName());
        //获取单位信息
        SocialUnitVo unit = getContacts(manufactor);
        obj.setUnitName(device.getUnitName());
        obj.setUnitId(device.getUnitId());
        obj.setCenterUnitId(unit.getCenterUnitId());
        obj.setDeviceName(device.getName());
        insertDevHisSsProducer.asyncSend(obj, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("=======发送插入DevHisSs消息成功=======");
            }

            @Override
            public void onException(Throwable throwable) {
                System.out.println("=======发送插入DevHisSs消息失败=======");
            }
        });
         // todo 目前bjztSm 为报警
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(obj.getZtfssj()).substring(11);
        if(obj.getBjztSm().contains("报警")) {
            List<EmergencyStaff> emergencyStaffList;
            emergencyStaffList = getZcEgencyStaffList(manufactor);

            if(emergencyStaffList.size()>0){
                aliMessageService.sendAliMessageBatch(emergencyStaffList, "唐山臻旭科技有限公司", "SMS_212709090", device.getName(), time, "");
                aliMessageService.sendAliVoiceBatch("", emergencyStaffList, "TTS_212477607", device.getName(), time);

            }
            //推送
            DevHisSSPushMessage devHisSSPushMessage = new DevHisSSPushMessage();
            devHisSSPushMessage.setAlarmTime(time);
            devHisSSPushMessage.setDevice(device);
            devHisSSPushMessage.setUnit(unit);
            devHisSSPushMessage.setDevHisId(obj.getId());
            devHisSSPushMessage.setDeviceName(device.getName());
            devHisSsPushProducer.asyncSend(devHisSSPushMessage, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.println("=======发送推送消息成功=======");
                }

                @Override
                public void onException(Throwable throwable) {
                    System.out.println("=======发送推送消息失败=======");
                }
            });
        }
        System.out.println("*************盛善----------");
        System.out.println(obj);
    }

    /**
     * 返回火灾自动报警设备报警信息
     *
     * @param handler
     * @param obj
     * @throws SocketTimeoutException
     * @throws IOException
     */
    @Override
    public void handleGB268753QN(ClientHandler handler, GB268753QN obj)
            throws SocketTimeoutException, IOException {
        try {
            if (null == obj || null == obj.getUniqueCode()) {
                return;
            }
            //获取主机
            Manufactor manufactor = JSON.parseObject((String) redisService.get(obj.getUniqueCode()), Manufactor.class);
            if (null == manufactor) {
                manufactor = manufactorService.selectCreateBy(obj.getUniqueCode());
            }
            if (null == manufactor) {
                return;
            }
            if (!"1".equals(manufactor.getIsOnline())) {
                manufactor.setIsOnline("1");
                manufactorService.updateStatusByIdentification(manufactor);
            }
            redisService.set(manufactor.getIdentification(), JSON.toJSONString(manufactor));
            //拼接报警状态
            Map<String, String> zt = obj.getComponentStateMap();
            List<String> bjztSm = new ArrayList<String>();
            List<String> bjzt = new ArrayList<String>();
            if (null != zt && zt.size() > 0) {
                for (Map.Entry<String, String> entry : zt.entrySet()) {
                    bjzt.add(entry.getKey());
                    bjztSm.add(entry.getValue());
                }
            }
            //拼接DevHis
            DevHis devHis = new DevHis();
            devHis.setId(UUIDUtils.getTimeUUID()); //code
            devHis.setDevCode(obj.getUniqueCode()); //传输装置唯一编码
            devHis.setUpTime(obj.getUploadTime()); //上传时间
            devHis.setLx(obj.getIsComponent()); //类型  1传输装置   2设备
            devHis.setZtfssj(obj.getStateTime()); //状态发生时间
            devHis.setBjzt(String.join(",", bjzt)); //部件状态码
            devHis.setBjztSm(String.join(",", bjztSm)); //部件状态中文说明
            devHis.setXtlx(obj.getSysType()); //系统类型
            devHis.setBjlx(obj.getComponentType());//部件类型
            devHis.setXtdz(obj.getSysAddress()); //系统地址
            devHis.setStatus("0"); //复核状态 默认未复核
            devHis.setHlh(obj.getLoopNumber()); //回路号
            devHis.setBjh(obj.getComponentNumber()); //部件号
            devHis.setEcm(obj.getTwiceCode()); //二次码
            devHis.setTd(obj.getTd()); //通道号
            devHis.setRelationId(obj.getId()); //id
            devHis.setUnitsCode(manufactor.getUnitId());
            System.out.println(devHis.toString());
            redisService.set(devHis.getId(), JSON.toJSONString(devHis), 3600L);
            //获取推送联系人
            SocialUnitVo unit = getContacts(manufactor);
            FirePushMessage firePushMessage = new FirePushMessage();
            firePushMessage.setDevHisId(devHis.getId());
            firePushMessage.setAlarmTime(devHis.getZtfssj());
            firePushMessage.setUnit(unit);
            //主机报警
            if ("1".equals(devHis.getLx())) {
                devHis.setDevName(manufactor.getName());
                devHis.setUnitsName(unit.getUnitName());
                devHis.setCenterUnitId(unit.getCenterUnitId());
                firePushMessage.setDeviceName(manufactor.getName());
                //rocketMQ异步消息===插入数据库
                insertDevHisProducer.asyncSend(devHis, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======发送插入DevHis消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======发送插入DevHis消息失败=======");
                    }
                });
                //火警
                if (bjzt.contains("08") && bjztSm.contains("火警")) {
                    firePushMessage.setKey("08");
                    firePushMessage.setIsAppPush(false);
                    //rocketMQ异步消息===websocket推送
                    firePushProducer.asyncSend(firePushMessage, new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println("=======发送消息成功=======");
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println("=======发送消息失败=======");
                        }
                    });
                    devHisResultService.saveOne(1, manufactor.getUnitId(), "");
                               /* //短信语音推送
                                aliMessageService.sendAliMessage(unit.getUserPhoneByUnitId().toString(),"唐山臻旭科技有限公司","SMS_212709090",unit.getUnitName(),manufactorName,devHis.getZtfssj().substring(11));
                                aliMessageService.batchSendAliVoice("",unit.getUserPhoneByUnitId());*/
                }
                //故障
                if (bjzt.contains("07") && !bjzt.contains("2404")) {
                    firePushMessage.setKey("07");
                    firePushMessage.setIsAppPush(false);
                    //rocketMQ异步消息===websocket推送
                    firePushProducer.asyncSend(firePushMessage, new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println("=======发送消息成功=======");
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println("=======发送消息失败=======");
                        }
                    });
                    devHisResultService.saveOne(2, manufactor.getUnitId(), "");
                }
            }
            //设备报警
            if ("2".equals(devHis.getLx())) {
                Device device = JSON.parseObject((String) redisService.get(devHis.getRelationId()), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(devHis.getRelationId());
                }
                if (device == null) {
                    return;
                }

                device.setStatus(devHis.getBjztSm());
                redisService.set(devHis.getRelationId(), JSON.toJSONString(device));
                String devName = device.getName();
                devHis.setDevName(devName);
                devHis.setUnitsName(unit.getUnitName());
                devHis.setCenterUnitId(unit.getCenterUnitId());
                //rocketMQ异步消息===插入数据库
                insertDevHisProducer.asyncSend(devHis, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======发送插入DevHis消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======发送插入DevHis消息失败=======");
                    }
                });
                String time = devHis.getZtfssj().substring(11);
                firePushMessage.setDeviceName(devName);
                //火警
                if (bjzt.contains("08")) {
                    devHisResultService.saveOne(1, device.getUnitId(), "");
                    //发送社会单位短信
                    System.out.println("=====================================================================================发送短信语音");
//                    //短信发送的电话号码可为多个用,分割例如：18818186444,17711111111
//                    List<String> phoneList;
//                    phoneList= getPhoneByUnitId(manufactor);
//                    aliMessageService.batchSendAliMessage(phoneList, "唐山臻旭科技有限公司", "SMS_212709090", device.getUnitName(), devName, time, unit.getUnitId());
//                    aliMessageService.batchSendAliVoice("", phoneList, "TTS_212477607", device.getUnitName() + devName, time, unit.getUnitId());

                    List<EmergencyStaff> emergencyStaffList;
                    emergencyStaffList = getEgencyStaffList(manufactor);
                    if(emergencyStaffList.size()>0){
                        aliMessageService.sendAliVoiceBatch("", emergencyStaffList, "TTS_212477607", devName, time);
                        aliMessageService.sendAliMessageBatch(emergencyStaffList, "唐山臻旭科技有限公司", "SMS_212709090", devName, time,"");
                    }
                    firePushMessage.setKey("08");
                    firePushMessage.setIsAppPush(true);
                    //rocketMQ异步消息===APP和Websocket推送
                    firePushProducer.asyncSend(firePushMessage, new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println("=======发送APP和websocket消息成功=======");
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println("=======发送APP和websocket消息失败=======");
                        }
                    });

                    judge(device, devHis.getZtfssj(), unit.getUnitUserIds().toArray(new String[0]));
                }
                //故障
                if (bjzt.contains("07") && !bjzt.contains("2404")) {
                    //保存故障设备信息
                    DeviceFault deviceFault = new DeviceFault();
                    deviceFault.setRelationId(device.getRelationId());
                    deviceFault.setDeviceName(device.getName());
                    deviceFault.setUnitId(device.getUnitId().toString());
                    deviceFault.setFaultTime(devHis.getZtfssj());
                    deviceFault.setDevHisId(devHis.getId());
                    devHisService.insertOrUpdateFaultDevice(deviceFault);
                    firePushMessage.setKey("07");
                    firePushMessage.setIsAppPush(true);
                    //rocketMQ异步消息===APP 和Websocket推送
                    firePushProducer.asyncSend(firePushMessage, new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println("=======发送APP和websocket消息成功=======");
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println("=======发送APP和websocket消息失败=======");
                        }
                    });
                    //计数
                    devHisResultService.saveOne(2, device.getUnitId(), "");
                }
                if (bjzt.contains(DevType.gzhf.getCode())) {
                    //获取设备最新的故障信息
                    DeviceFault deviceFault = JSON.parseObject((String) redisService.get(device.getRelationId() + "-fault"), DeviceFault.class);
                    if (deviceFault == null) {
                        deviceFault = devHisService.queryById(device.getRelationId());
                    }
                    if (deviceFault != null) {
                        //获取设备有效恢复时间
                        EffectiveTimeSetting effectiveTimeSetting = JSON.parseObject((String) redisService.get("effectiveTime-" + device.getUnitId()), EffectiveTimeSetting.class);
                        if (null == effectiveTimeSetting) {
                            effectiveTimeSetting = devHisService.getEffectiveTimeSetting(device.getUnitId());
                            redisService.set("effectiveTime-" + device.getUnitId(), JSON.toJSONString(effectiveTimeSetting));
                        }

                        FaultRecoveryRecord faultRecoveryRecord = new FaultRecoveryRecord();
                        faultRecoveryRecord.setId(UUIDUtils.get32UUID());
                        faultRecoveryRecord.setDevHisId(deviceFault.getDevHisId());
                        faultRecoveryRecord.setUnitId(device.getUnitId());
                        faultRecoveryRecord.setHfTime(devHis.getZtfssj());
                        String ztfssj = deviceFault.getFaultTime();
                        String gzhfsj = devHis.getZtfssj();
                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        LocalDateTime startTime = LocalDateTime.parse(ztfssj, dateTimeFormatter);
                        LocalDateTime endTime = LocalDateTime.parse(gzhfsj, dateTimeFormatter);
                        long between = ChronoUnit.MINUTES.between(startTime, endTime);
                        if (between > effectiveTimeSetting.getFaultTime()) {
                            faultRecoveryRecord.setIsEffective(0);
                        } else {
                            faultRecoveryRecord.setIsEffective(1);
                        }
                        devHisService.insetFaultRecoveryRecord(faultRecoveryRecord);
                        //删除已恢复的故障设备信息
                        devHisService.deleteFaultDevice(deviceFault.getRelationId());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭   主动关闭客户端
     *
     * @param handler
     * @param uniqueCode
     * @throws IOException
     */
    @Override
    public void closingDev(ClientHandler handler, String uniqueCode)
            throws IOException {
        try {
            //System.out.println("lostDev---------------"+uniqueCode);
            if ("0".equals(uniqueCode)) {
                return;
            }
            System.out.println("closingDev---------------"+uniqueCode);
            String type = handler.getClientData().toString();
            if (type.contains("ZCServerData")){
                System.out.println("庄诚下线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.del(uniqueCode);
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisZc devHisZc = new DevHisZc();
                devHisZc.setId((UUIDUtils.getTimeUUID()));
                devHisZc.setDevCode(uniqueCode);
                devHisZc.setUpTime(new Date());
                devHisZc.setZtfssj(new Date());
                devHisZc.setBjzt(DevType.cszglx.getCode());
                devHisZc.setBjztSm(DevType.cszglx.getName());
                devHisZc.setUnitId(device.getUnitId());
                devHisZc.setUnitName(device.getUnitName());
                devHisZc.setCenterUnitId(unit.getCenterUnitId());
                devHisZc.setDeviceName(device.getName());
                insertDevHisZcProducer.asyncSend(devHisZc, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======上线发送插入DevHisZc消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======上线发送插入DevHisZc消息失败=======");
                    }
                });
                return;
            }

            if (type.contains("ShengShanServerData")){
                System.out.println("盛善下线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.del(uniqueCode);
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisSs devHisSs = new DevHisSs();
                devHisSs.setId((UUIDUtils.getTimeUUID()));
                devHisSs.setDevCode(uniqueCode);
                devHisSs.setUpTime(new Date());
                devHisSs.setZtfssj(new Date());
                devHisSs.setBjzt(DevType.cszglx.getCode());
                devHisSs.setBjztSm(DevType.cszglx.getName());
                devHisSs.setUnitId(device.getUnitId());
                devHisSs.setUnitName(device.getUnitName());
                devHisSs.setCenterUnitId(unit.getCenterUnitId());
                insertDevHisSsProducer.asyncSend(devHisSs, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======下线发送插入DevHisSs消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======下线发送插入DevHisSs消息失败=======");
                    }
                });
                return;
            }

            //获取主机
            Manufactor manufactor = JSON.parseObject((String) redisService.get(uniqueCode), Manufactor.class);
            if (null == manufactor) {
                manufactor = manufactorService.selectCreateBy(uniqueCode);
            }
            if (null == manufactor) {
                return;
            }
            //修改主机在线状态
            if ("1".equals(manufactor.getIsOnline())) {
                manufactor.setIsOnline("0");
                manufactorService.updateStatusByIdentification(manufactor);
            }
            redisService.set(uniqueCode, JSON.toJSONString(manufactor));
            //获取联系人
            SocialUnitVo unit = getContacts(manufactor);

            System.out.println(uniqueCode + "close");
            String s = handler.getClientData().toString();
            String id = UUIDUtils.getTimeUUID();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String ztfssj = sdf.format(new Date());
            //运行记录入库
            if (s.contains("SZGW")) {
                System.out.println("苏州国网");
                DevHisWater devHisWater = new DevHisWater();
                devHisWater.setId(id); //code
                devHisWater.setManufactorIdentification(uniqueCode); //传输装置唯一编码
                devHisWater.setRelationId(uniqueCode);
                devHisWater.setUploadTime(ztfssj); //上传时间
                devHisWater.setSysType("1"); //类型  1传输装置   2设备
                devHisWater.setStateTime(ztfssj); //状态发生时间
                devHisWater.setComponentStatus(DevType.cszglx.getName()); //部件状态码
                devHisWater.setComponentExplain(DevType.cszglx.getCode()); //部件状态中文说明
                devHisWater.setUnitId(manufactor.getUnitId());
                devHisWater.setUnitName(unit.getUnitName());
                devHisWater.setDeviceName(manufactor.getName());
                EsDevHisWater esDevHisWater = new EsDevHisWater();
                BeanUtils.copyProperties(devHisWater, esDevHisWater);
                esDevHisWaterService.importAll(esDevHisWater);
                devHisService.insertDevHisWater(devHisWater);
            }else {
                DevHis devHis = new DevHis();
                devHis.setId(id); //code
                devHis.setDevCode(uniqueCode); //传输装置唯一编码
                devHis.setUpTime(ztfssj); //上传时间
                devHis.setLx("3"); //类型  类型：主机1；设备：2    用户传输装置  3
                devHis.setZtfssj(ztfssj); //状态发生时间
                devHis.setBjzt(DevType.cszglx.getCode()); //部件状态码
                devHis.setBjztSm(DevType.cszglx.getName()); //部件状态中文说明
                devHis.setStatus("0"); //复核状态 默认未复核
                devHis.setRelationId(uniqueCode); //id
                devHis.setUnitsCode(manufactor.getUnitId());
                devHis.setUnitsName(unit.getUnitName());
                System.out.println(devHis.toString());
                EsDevHis esDevHis = new EsDevHis();
                BeanUtils.copyProperties(devHis, esDevHis);
                esDevHis.setUnitId(devHis.getUnitsCode());
                esDevHis = esDevHisService.importAll(esDevHis);
                devHisService.insertHis(devHis);
            }
            //离线通知推送
            MoreMessage moreMessage = new MoreMessage();
            moreMessage.setUserIds(unit.getUnitUserIds().toArray(new String[0]));
            moreMessage.setCmd(WebsocketConstant.CMD_TOPIC);
            moreMessage.setMsgId(id);
            moreMessage.setMsgTitle("主机离线通知");
            moreMessage.setMsgTxt(manufactor.getName() + "于" + ztfssj + "已下线");
            redisService.convertAndSend("channel:moreMessage", moreMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 丢失    客户端主动断开连接
     *
     * @param handler
     * @param uniqueCode
     * @throws IOException
     */
    @Override
    public void lostDev(ClientHandler handler, String uniqueCode)
            throws IOException {
        try {
            System.out.println("lostDev---------------"+uniqueCode);
            if ("0".equals(uniqueCode)) {
                return;
            }
            System.out.println("lostDev---------------"+uniqueCode);
            String type = handler.getClientData().toString();
            if (type.contains("ZCServerData")){
                System.out.println("庄诚下线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.del(uniqueCode);
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisZc devHisZc = new DevHisZc();
                devHisZc.setId((UUIDUtils.getTimeUUID()));
                devHisZc.setDevCode(uniqueCode);
                devHisZc.setUpTime(new Date());
                devHisZc.setZtfssj(new Date());
                devHisZc.setBjzt(DevType.cszglx.getCode());
                devHisZc.setBjztSm(DevType.cszglx.getName());
                devHisZc.setUnitId(device.getUnitId());
                devHisZc.setUnitName(device.getUnitName());
                devHisZc.setCenterUnitId(unit.getCenterUnitId());
                devHisZc.setDeviceName(device.getName());
                insertDevHisZcProducer.asyncSend(devHisZc, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======上线发送插入DevHisZc消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======上线发送插入DevHisZc消息失败=======");
                    }
                });
                return;
            }
            if (type.contains("ShengShanServerData")){
                System.out.println("盛善下线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.del(uniqueCode);
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisSs devHisSs = new DevHisSs();
                devHisSs.setId((UUIDUtils.getTimeUUID()));
                devHisSs.setDevCode(uniqueCode);
                devHisSs.setUpTime(new Date());
                devHisSs.setZtfssj(new Date());
                devHisSs.setBjzt(DevType.cszglx.getCode());
                devHisSs.setBjztSm(DevType.cszglx.getName());
                devHisSs.setUnitId(device.getUnitId());
                devHisSs.setUnitName(device.getUnitName());
                devHisSs.setCenterUnitId(unit.getCenterUnitId());
                insertDevHisSsProducer.asyncSend(devHisSs, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======下线发送插入DevHisSs消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======下线发送插入DevHisSs消息失败=======");
                    }
                });
                return;
            }
            //获取主机
            Manufactor manufactor = JSON.parseObject((String) redisService.get(uniqueCode), Manufactor.class);
            if (null == manufactor) {
                manufactor = manufactorService.selectCreateBy(uniqueCode);
            }
            if (null == manufactor) {
                return;
            }
            //修改主机在线状态
            if ("1".equals(manufactor.getIsOnline())) {
                manufactor.setIsOnline("0");
                manufactorService.updateStatusByIdentification(manufactor);
            }
            redisService.set(uniqueCode, JSON.toJSONString(manufactor));
            //获取联系人
            SocialUnitVo unit = getContacts(manufactor);

            System.out.println(uniqueCode + "lost");
            String s = handler.getClientData().toString();
            String id = UUIDUtils.getTimeUUID();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String ztfssj = sdf.format(new Date());
            if(s.contains("SZGW")){
                System.out.println("苏州国网");
                DevHisWater devHisWater = new DevHisWater();
                devHisWater.setId(id); //code
                devHisWater.setManufactorIdentification(uniqueCode); //传输装置唯一编码
                devHisWater.setRelationId(uniqueCode);
                devHisWater.setUploadTime(ztfssj); //上传时间
                devHisWater.setSysType("1"); //类型  1传输装置   2设备
                devHisWater.setStateTime(ztfssj); //状态发生时间
                devHisWater.setComponentStatus(DevType.cszglx.getName()); //部件状态码
                devHisWater.setComponentExplain(DevType.cszglx.getCode()); //部件状态中文说明
                devHisWater.setUnitId(manufactor.getUnitId());
                devHisWater.setUnitName(unit.getUnitName());
                devHisWater.setDeviceName(manufactor.getName());
                EsDevHisWater esDevHisWater = new EsDevHisWater();
                BeanUtils.copyProperties(devHisWater, esDevHisWater);
                esDevHisWaterService.importAll(esDevHisWater);
                devHisService.insertDevHisWater(devHisWater);
            }else {
                DevHis devHis = new DevHis();
                devHis.setId(id); //code
                devHis.setDevCode(uniqueCode); //传输装置唯一编码
                devHis.setUpTime(ztfssj); //上传时间
                devHis.setLx("3"); //类型：主机1；设备：2    用户传输装置  3
                devHis.setZtfssj(ztfssj); //状态发生时间
                devHis.setBjzt(DevType.cszglx.getCode()); //部件状态码
                devHis.setBjztSm(DevType.cszglx.getName()); //部件状态中文说明
                devHis.setStatus("0"); //复核状态 默认未复核
                devHis.setRelationId(uniqueCode); //id
                devHis.setUnitsCode(manufactor.getUnitId());
                devHis.setUnitsName(unit.getUnitName());
                System.out.println(devHis.toString());
                EsDevHis esDevHis = new EsDevHis();
                BeanUtils.copyProperties(devHis, esDevHis);
                esDevHis.setUnitId(devHis.getUnitsCode());
                esDevHis = esDevHisService.importAll(esDevHis);
                devHisService.insertHis(devHis);
            }
            //离线通知推送
            MoreMessage moreMessage = new MoreMessage();
            moreMessage.setUserIds(unit.getUnitUserIds().toArray(new String[0]));
            moreMessage.setCmd(WebsocketConstant.CMD_TOPIC);
            moreMessage.setMsgId(id);
            moreMessage.setMsgTitle("主机离线通知");
            moreMessage.setMsgTxt(manufactor.getName() + "于" + ztfssj + "已下线");
            redisService.convertAndSend("channel:moreMessage", moreMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 上线
     *
     * @param handler
     * @param uniqueCode
     * @throws SocketTimeoutException
     * @throws IOException
     */
    @Override
    public void gotConnectDev(ClientHandler handler, String uniqueCode)
            throws SocketTimeoutException, IOException {
        try {
            if ("0".equals(uniqueCode)) {
                return;
            }

            System.out.println(uniqueCode + "conn");
            String type = handler.getClientData().toString();
            if (type.contains("ZCServerData")){
                System.out.println("庄诚上线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.set(uniqueCode, JSON.toJSONString(device));
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisZc devHisZc = new DevHisZc();
                devHisZc.setId((UUIDUtils.getTimeUUID()));
                devHisZc.setDevCode(uniqueCode);
                devHisZc.setUpTime(new Date());
                devHisZc.setZtfssj(new Date());
                devHisZc.setBjzt(DevType.cszgsx.getCode());
                devHisZc.setBjztSm(DevType.cszgsx.getName());
                devHisZc.setUnitId(device.getUnitId());
                devHisZc.setUnitName(device.getUnitName());
                devHisZc.setCenterUnitId(unit.getCenterUnitId());
                devHisZc.setDeviceName(device.getName());
                insertDevHisZcProducer.asyncSend(devHisZc, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======上线发送插入DevHisZc消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======上线发送插入DevHisZc消息失败=======");
                    }
                });
                return;
            }

            if (type.contains("ShengShanServerData")){
                System.out.println("盛善上线了");
                Device device = JSON.parseObject((String) redisService.get(uniqueCode), Device.class);
                if (device == null) {
                    device = devHisService.queryCreateBy(uniqueCode);
                }
                if (device == null) {
                    return;
                }
                redisService.set(uniqueCode, JSON.toJSONString(device));
                //虚拟一个主机，调用通过主机获取推送人的方法
                Manufactor manufactor = new Manufactor();
                manufactor.setIdentification(device.getRelationId());
                manufactor.setUnitId(device.getUnitId());
                manufactor.setUnitName(device.getUnitName());

                //获取单位信息
                SocialUnitVo unit = getContacts(manufactor);

                DevHisSs devHisSs = new DevHisSs();
                devHisSs.setId((UUIDUtils.getTimeUUID()));
                devHisSs.setDevCode(uniqueCode);
                devHisSs.setUpTime(new Date());
                devHisSs.setZtfssj(new Date());
                devHisSs.setBjzt(DevType.cszgsx.getCode());
                devHisSs.setBjztSm(DevType.cszgsx.getName());
                devHisSs.setUnitId(device.getUnitId());
                devHisSs.setUnitName(device.getUnitName());
                devHisSs.setCenterUnitId(unit.getCenterUnitId());
                insertDevHisSsProducer.asyncSend(devHisSs, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("=======上线发送插入DevHisSs消息成功=======");
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("=======上线发送插入DevHisSs消息失败=======");
                    }
                });
                return;
            }

            //获取主机
            Object o = redisService.get(uniqueCode);
            Manufactor manufactor = JSON.parseObject((String) redisService.get(uniqueCode), Manufactor.class);
            if (null == manufactor) {
                manufactor = manufactorService.selectCreateBy(uniqueCode);
            }
            if (null == manufactor) {
                return;
            }
            //修改主机在线状态
            if ("0".equals(manufactor.getIsOnline())) {
                manufactor.setIsOnline("1");
                manufactorService.updateStatusByIdentification(manufactor);
            }
            redisService.set(uniqueCode, JSON.toJSONString(manufactor));
            //获取通知联系人
            SocialUnitVo unit = getContacts(manufactor);

            String s = handler.getClientData().toString();
            String id = UUIDUtils.getTimeUUID();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String ztfssj = sdf.format(new Date());
            if (s.contains("SZGW")) {
                System.out.println("苏州国网");
                DevHisWater devHisWater = new DevHisWater();
                devHisWater.setId(id); //code
                devHisWater.setManufactorIdentification(uniqueCode); //传输装置唯一编码
                devHisWater.setRelationId(uniqueCode);
                devHisWater.setUploadTime(ztfssj); //上传时间
                devHisWater.setSysType("1"); //类型  1传输装置   2设备
                devHisWater.setStateTime(ztfssj); //状态发生时间
                devHisWater.setComponentStatus(DevType.cszgsx.getName()); //部件状态码
                devHisWater.setComponentExplain(DevType.cszgsx.getCode()); //部件状态中文说明
                devHisWater.setUnitId(manufactor.getUnitId());
                devHisWater.setUnitName(unit.getUnitName());
                devHisWater.setDeviceName(manufactor.getName());
                EsDevHisWater esDevHisWater = new EsDevHisWater();
                BeanUtils.copyProperties(devHisWater, esDevHisWater);
                esDevHisWaterService.importAll(esDevHisWater);
                devHisService.insertDevHisWater(devHisWater);
            } else {
                DevHis devHis = new DevHis();
                devHis.setId(id); //code
                devHis.setDevCode(uniqueCode); //传输装置唯一编码
                devHis.setUpTime(ztfssj); //上传时间
                devHis.setLx("3"); //类型：主机1；设备：2    用户传输装置  3
                devHis.setZtfssj(ztfssj); //状态发生时间
                devHis.setBjzt(DevType.cszgsx.getCode()); //部件状态码
                devHis.setBjztSm(DevType.cszgsx.getName()); //部件状态中文说明
                devHis.setStatus("0"); //复核状态 默认未复核
                devHis.setRelationId(uniqueCode); //id
                devHis.setUnitsCode(manufactor.getUnitId());
                devHis.setDevName(manufactor.getName());
                devHis.setUnitsName(unit.getUnitName());
                System.out.println(devHis.toString());
                EsDevHis esDevHis = new EsDevHis();
                BeanUtils.copyProperties(devHis, esDevHis);
                esDevHis.setUnitId(devHis.getUnitsCode());
                esDevHis = esDevHisService.importAll(esDevHis);
                devHisService.insertHis(devHis);
            }

            //上线通知推送
            MoreMessage moreMessage = new MoreMessage();
            moreMessage.setUserIds(unit.getUnitUserIds().toArray(new String[0]));
            moreMessage.setCmd(WebsocketConstant.CMD_TOPIC);
            //moreMessage.setMsgId(devHis.getId());
            moreMessage.setMsgId(id);
            moreMessage.setMsgTitle("主机上线通知");
            moreMessage.setMsgTxt(manufactor.getName() + "于" + ztfssj + "已上线");
            redisService.convertAndSend("channel:moreMessage", moreMessage);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void judge(Device device, String ztfssj, String[] unitUserId) {
        Map<String, String> params = new HashMap<>();
        params.put("unitId", device.getUnitId());
        List<Device> alarmDevice = new ArrayList<>();
        //判断设备是海湾或其他
        if (StringUtils.isNotBlank(device.getSecondaryCode())) {//海湾设备
            params.put("secondaryCode", device.getSecondaryCode());
            alarmDevice = devHisService.getDevices(params);
        } else {//青鸟或利达设备
            params.put("loopNumber", device.getLoopNumber());
            alarmDevice = devHisService.getDevices(params);
        }
        List<String> ids = new ArrayList<>();
        List<String> names = new ArrayList<>();
        for (int i = 0; i < alarmDevice.size(); i++) {
            ids.add(alarmDevice.get(i).getRelationId());
        }
        //获取一定时间内的报警数据
        List<DevHisVo> devHiss = devHisService.getDevHiss(ids.toArray(new String[0]), ztfssj);
        List<String> devHisIds = new ArrayList<>();
        if (devHiss.size() > 3) {//疑似火警推送
            for (DevHisVo dvo : devHiss) {
                names.add(dvo.getDeviceName());
                devHisIds.add(dvo.getId());
            }
            //去重
            List<String> names1 = names.stream().distinct().collect(Collectors.toList());
            SuspectedFire suspectedFire = new SuspectedFire();
            suspectedFire.setId(UUIDUtils.get32UUID());
            suspectedFire.setCreateBy("系统");
            suspectedFire.setCreateTime(new Date());
            suspectedFire.setUnitId(device.getUnitId());
            suspectedFire.setDevHisIds(devHisIds.toString());
            String msg = "尊敬的用户您好，" + names1.toString() + "等设备短时间内多次上报火警，请您及时确认处理！";
            suspectedFire.setMsgInfo(msg);
            MoreMessage moreMessage = new MoreMessage();
            moreMessage.setUserIds(unitUserId);
            moreMessage.setCmd(WebsocketConstant.CMD_YSFIRE);
            moreMessage.setMsgId(suspectedFire.getId());
            moreMessage.setMsgTitle("疑似火警通知");
            moreMessage.setMsgTxt(msg);
            redisService.convertAndSend("channel:moreMessage", moreMessage);
            suspectedFireService.insertSuspectedFire(suspectedFire);
        }

    }

    private SocialUnitVo getContacts(Manufactor manufactor) {
        SocialUnitVo unit = JSON.parseObject((String) redisService.get(manufactor.getIdentification() + "-unit"), SocialUnitVo.class);
        if (null == unit) {
            List<EmergencyStaff> list = iEmergencyStaffService.getByUnitid(manufactor.getUnitId());
            unit = new SocialUnitVo();
            List<String> ls = list.stream().map(EmergencyStaff::getMobile).collect(Collectors.toList());
            unit.setUserPhoneByUnitId(ls);

            Map<String, Object> centerUnit = sysUserService.getCenterUnit(manufactor.getUnitId());
            unit.setUnitId(manufactor.getUnitId());
            unit.setUnitName(manufactor.getUnitName());
            unit.setCenterUnitId(centerUnit.get("id").toString());
            unit.setCenterUnitName(centerUnit.get("name").toString());
            unit.setUnitUserIds(sysUserService.getUserByUnitId(manufactor.getUnitId()));
            //unit.setUserPhoneByUnitId(sysUserService.getUserPhoneByUnitId(manufactor.getUnitId()));
            unit.setCenterUserIds(sysUserService.getCenterUserByUnitId(manufactor.getUnitId()));
            unit.setCenterUserPhoneByUnitId(sysUserService.getCenterUserPhoneByUnitId(manufactor.getUnitId()));

            List<String> idList = sysUserService.getUnitIds(manufactor.getUnitId());
            List<String> centerIds = unit.getCenterUserIds();
            List<String> unitIds = new ArrayList<>();
            for (String centerid : centerIds) {
                for (String unitid : idList){
                    unitIds.add(centerid+"-"+unitid);
                }
            }
            unit.setUnitIds(unitIds);

            redisService.set(manufactor.getIdentification() + "-unit", JSON.toJSONString(unit));
        }
        return unit;
    }

    private List<String> getPhoneByUnitId(Manufactor manufactor) {
        List<EmergencyStaff> list = iEmergencyStaffService.getByUnitid(manufactor.getUnitId());
        return list.stream().map(EmergencyStaff::getMobile).collect(Collectors.toList());
    }

    private List<EmergencyStaff> getEgencyStaffList(Manufactor manufactor) {
        return iEmergencyStaffService.getByUnitid(manufactor.getUnitId());
    }

    private List<EmergencyStaff> getWaterEgencyStaffList(Manufactor manufactor) {
        return iEmergencyStaffService.getWaterStaffByUnitid(manufactor.getUnitId());
    }
    private List<EmergencyStaff> getZcEgencyStaffList(Manufactor manufactor) {
        return iEmergencyStaffService.getZcStaffByUnitid(manufactor.getUnitId());
    }

}
